Enter the directory of the maca folder on your drive and the name of the tissue you want to analyze.

tissue_of_interest = "Aorta"

Load the requisite packages and some additional helper functions.

library(here)
here() starts at /Users/olgabot/code/tabula-muris
library(useful)
Loading required package: ggplot2
library(Seurat)
Loading required package: cowplot

Attaching package: ‘cowplot’

The following object is masked from ‘package:ggplot2’:

    ggsave

Loading required package: Matrix
namespace ‘Biobase’ is not available and has been replaced
by .GlobalEnv when processing object ‘options’namespace ‘lme4’ is not available and has been replaced
by .GlobalEnv when processing object ‘options’namespace ‘MatrixModels’ is not available and has been replaced
by .GlobalEnv when processing object ‘options’namespace ‘Biobase’ is not available and has been replaced
by .GlobalEnv when processing object ‘options’namespace ‘lme4’ is not available and has been replaced
by .GlobalEnv when processing object ‘options’namespace ‘MatrixModels’ is not available and has been replaced
by .GlobalEnv when processing object ‘options’
library(dplyr)
package ‘dplyr’ was built under R version 3.4.2
Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(Matrix)
save_dir = here('00_data_ingest', 'tissue_robj')

Load the plate metadata. Check which plates have been downloaded.

plate_metadata_filename = here('00_data_ingest', 'facs_raw_data', 'metadata_FACS.csv')
plate_metadata <- read.csv(plate_metadata_filename, sep=",", header = TRUE)
colnames(plate_metadata)[1] <- "plate.barcode"
plate_metadata
# count_files = list.files(paste0(rootdir, "/data/plates"), pattern = "*counts.tab",recursive = FALSE)
# downloaded_plates = lapply(count_files, function(x) strsplit(x,"[./]")[[1]][1])
# plate_metadata = plate_metadata[plate_metadata$plate.barcode %in% downloaded_plates,]
# 
# save_dir = paste0(rootdir, '/save')
# dir.create(save_dir)

“Aorta” is a subtissue of “Heart” and we will have to filter for this.

tissue_plates = filter(plate_metadata, subtissue == tissue_of_interest)[,c('plate.barcode','tissue','subtissue','mouse.sex')]
tissue_plates

Load the read count data.

#Load the gene names and set the metadata columns by opening the first file
filename = here('00_data_ingest', 'facs_raw_data', 'FACS', 'Heart-counts.csv')
raw.data = read.csv(filename, sep=",", row.names=1)
# raw.data = data.frame(row.names = rownames(raw.data))
corner(raw.data)

Use only cells from “Aorta”" plate barcodes.

plate.barcodes = lapply(colnames(raw.data), function(x) strsplit(strsplit(x, "_")[[1]][1], '.', fixed=TRUE)[[1]][2])
head(plate.barcodes)
[[1]]
[1] "MAA000398"

[[2]]
[1] "MAA000398"

[[3]]
[1] "MAA000398"

[[4]]
[1] "MAA000398"

[[5]]
[1] "MAA000398"

[[6]]
[1] "MAA000398"
aorta.plates = filter(tissue_plates, subtissue == "Aorta")
aorta.barcodes = plate.barcodes %in% aorta.plates$plate.barcode
sum(aorta.barcodes)
[1] 1113

Use only the aorta barcodes

raw.data = raw.data[aorta.barcodes]
meta.data = plate_metadata[plate_metadata$plate.barcode %in% plate.barcodes, ]
dim(plate_metadata)
[1] 247   6
dim(meta.data)
[1] 36  6
corner(meta.data)
barcode.df = t.data.frame(as.data.frame(plate.barcodes[aorta.barcodes]))
head(barcode.df)
               [,1]       
X.MAA000594.   "MAA000594"
X.MAA000594..1 "MAA000594"
X.MAA000594..2 "MAA000594"
X.MAA000594..3 "MAA000594"
X.MAA000594..4 "MAA000594"
X.MAA000594..5 "MAA000594"
dim(raw.data)
[1] 23433  1113
rownames(barcode.df) = colnames(raw.data)
colnames(barcode.df) = c('plate.barcode')
head(barcode.df)
                        plate.barcode
A21.MAA000594.3_8_M.1.1 "MAA000594"  
D1.MAA000594.3_8_M.1.1  "MAA000594"  
F8.MAA000594.3_8_M.1.1  "MAA000594"  
H11.MAA000594.3_8_M.1.1 "MAA000594"  
N15.MAA000594.3_8_M.1.1 "MAA000594"  
P3.MAA000594.3_8_M.1.1  "MAA000594"  
head(plate_metadata)
rnames = row.names(barcode.df)
meta.data <- merge(barcode.df, plate_metadata, by='plate.barcode', sort = F)
row.names(meta.data) <- rnames
head(meta.data)

Process the raw data and load it into the Seurat object.

# Find ERCC's, compute the percent ERCC, and drop them from the raw data.
erccs <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = TRUE)
percent.ercc <- Matrix::colSums(raw.data[erccs, ])/Matrix::colSums(raw.data)
ercc.index <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = FALSE)
raw.data <- raw.data[-ercc.index,]
# Create the Seurat object with all the data
tiss <- CreateSeuratObject(raw.data = raw.data, project = tissue_of_interest, 
                    min.cells = 5, min.genes = 5)
tiss <- AddMetaData(object = tiss, meta.data)
tiss <- AddMetaData(object = tiss, percent.ercc, col.name = "percent.ercc")
# Change default name for sums of counts from nUMI to nReads
colnames(tiss@meta.data)[colnames(tiss@meta.data) == 'nUMI'] <- 'nReads'
# Create metadata columns for annotations and subannotations
tiss@meta.data[,'annotation'] <- NA
tiss@meta.data[,'subannotation'] <- NA

Calculate percent ribosomal genes.

ribo.genes <- grep(pattern = "^Rp[sl][[:digit:]]", x = rownames(x = tiss@data), value = TRUE)
percent.ribo <- Matrix::colSums(tiss@raw.data[ribo.genes, ])/Matrix::colSums(tiss@raw.data)
tiss <- AddMetaData(object = tiss, metadata = percent.ribo, col.name = "percent.ribo")

A sanity check: genes per cell vs reads per cell.

GenePlot(object = tiss, gene1 = "nReads", gene2 = "nGene", use.raw=T)

Filter out cells with few reads and few genes.

tiss <- FilterCells(object = tiss, subset.names = c("nGene", "nReads"), 
    low.thresholds = c(500, 50000), high.thresholds = c(25000, 2000000))

Normalize the data, then regress out correlation with total reads

tiss <- NormalizeData(object = tiss)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
**************************************************|
tiss <- ScaleData(object = tiss, vars.to.regress = c("nReads", "percent.ribo","Rn45s"))
[1] "Regressing out nReads"       "Regressing out percent.ribo"
[3] "Regressing out Rn45s"       

  |                                                                                      
  |                                                                                |   0%
  |                                                                                      
  |                                                                                |   1%
  |                                                                                      
  |=                                                                               |   1%
  |                                                                                      
  |=                                                                               |   2%
  |                                                                                      
  |==                                                                              |   2%
  |                                                                                      
  |==                                                                              |   3%
  |                                                                                      
  |===                                                                             |   4%
  |                                                                                      
  |====                                                                            |   5%
  |                                                                                      
  |====                                                                            |   6%
  |                                                                                      
  |=====                                                                           |   6%
  |                                                                                      
  |=====                                                                           |   7%
  |                                                                                      
  |======                                                                          |   7%
  |                                                                                      
  |======                                                                          |   8%
  |                                                                                      
  |=======                                                                         |   9%
  |                                                                                      
  |========                                                                        |  10%
  |                                                                                      
  |========                                                                        |  11%
  |                                                                                      
  |=========                                                                       |  11%
  |                                                                                      
  |=========                                                                       |  12%
  |                                                                                      
  |==========                                                                      |  12%
  |                                                                                      
  |==========                                                                      |  13%
  |                                                                                      
  |===========                                                                     |  13%
  |                                                                                      
  |===========                                                                     |  14%
  |                                                                                      
  |============                                                                    |  15%
  |                                                                                      
  |=============                                                                   |  16%
  |                                                                                      
  |=============                                                                   |  17%
  |                                                                                      
  |==============                                                                  |  17%
  |                                                                                      
  |==============                                                                  |  18%
  |                                                                                      
  |===============                                                                 |  18%
  |                                                                                      
  |===============                                                                 |  19%
  |                                                                                      
  |================                                                                |  20%
  |                                                                                      
  |=================                                                               |  21%
  |                                                                                      
  |=================                                                               |  22%
  |                                                                                      
  |==================                                                              |  22%
  |                                                                                      
  |==================                                                              |  23%
  |                                                                                      
  |===================                                                             |  23%
  |                                                                                      
  |===================                                                             |  24%
  |                                                                                      
  |====================                                                            |  25%
  |                                                                                      
  |=====================                                                           |  26%
  |                                                                                      
  |=====================                                                           |  27%
  |                                                                                      
  |======================                                                          |  27%
  |                                                                                      
  |======================                                                          |  28%
  |                                                                                      
  |=======================                                                         |  28%
  |                                                                                      
  |=======================                                                         |  29%
  |                                                                                      
  |========================                                                        |  30%
  |                                                                                      
  |=========================                                                       |  31%
  |                                                                                      
  |=========================                                                       |  32%
  |                                                                                      
  |==========================                                                      |  32%
  |                                                                                      
  |==========================                                                      |  33%
  |                                                                                      
  |===========================                                                     |  33%
  |                                                                                      
  |===========================                                                     |  34%
  |                                                                                      
  |============================                                                    |  35%
  |                                                                                      
  |=============================                                                   |  36%
  |                                                                                      
  |=============================                                                   |  37%
  |                                                                                      
  |==============================                                                  |  37%
  |                                                                                      
  |==============================                                                  |  38%
  |                                                                                      
  |===============================                                                 |  38%
  |                                                                                      
  |===============================                                                 |  39%
  |                                                                                      
  |================================                                                |  39%
  |                                                                                      
  |================================                                                |  40%
  |                                                                                      
  |=================================                                               |  41%
  |                                                                                      
  |==================================                                              |  42%
  |                                                                                      
  |==================================                                              |  43%
  |                                                                                      
  |===================================                                             |  43%
  |                                                                                      
  |===================================                                             |  44%
  |                                                                                      
  |====================================                                            |  44%
  |                                                                                      
  |====================================                                            |  45%
  |                                                                                      
  |=====================================                                           |  46%
  |                                                                                      
  |======================================                                          |  47%
  |                                                                                      
  |======================================                                          |  48%
  |                                                                                      
  |=======================================                                         |  48%
  |                                                                                      
  |=======================================                                         |  49%
  |                                                                                      
  |========================================                                        |  49%
  |                                                                                      
  |========================================                                        |  50%
  |                                                                                      
  |========================================                                        |  51%
  |                                                                                      
  |=========================================                                       |  51%
  |                                                                                      
  |=========================================                                       |  52%
  |                                                                                      
  |==========================================                                      |  52%
  |                                                                                      
  |==========================================                                      |  53%
  |                                                                                      
  |===========================================                                     |  54%
  |                                                                                      
  |============================================                                    |  55%
  |                                                                                      
  |============================================                                    |  56%
  |                                                                                      
  |=============================================                                   |  56%
  |                                                                                      
  |=============================================                                   |  57%
  |                                                                                      
  |==============================================                                  |  57%
  |                                                                                      
  |==============================================                                  |  58%
  |                                                                                      
  |===============================================                                 |  59%
  |                                                                                      
  |================================================                                |  60%
  |                                                                                      
  |================================================                                |  61%
  |                                                                                      
  |=================================================                               |  61%
  |                                                                                      
  |=================================================                               |  62%
  |                                                                                      
  |==================================================                              |  62%
  |                                                                                      
  |==================================================                              |  63%
  |                                                                                      
  |===================================================                             |  63%
  |                                                                                      
  |===================================================                             |  64%
  |                                                                                      
  |====================================================                            |  65%
  |                                                                                      
  |=====================================================                           |  66%
  |                                                                                      
  |=====================================================                           |  67%
  |                                                                                      
  |======================================================                          |  67%
  |                                                                                      
  |======================================================                          |  68%
  |                                                                                      
  |=======================================================                         |  68%
  |                                                                                      
  |=======================================================                         |  69%
  |                                                                                      
  |========================================================                        |  70%
  |                                                                                      
  |=========================================================                       |  71%
  |                                                                                      
  |=========================================================                       |  72%
  |                                                                                      
  |==========================================================                      |  72%
  |                                                                                      
  |==========================================================                      |  73%
  |                                                                                      
  |===========================================================                     |  73%
  |                                                                                      
  |===========================================================                     |  74%
  |                                                                                      
  |============================================================                    |  75%
  |                                                                                      
  |=============================================================                   |  76%
  |                                                                                      
  |=============================================================                   |  77%
  |                                                                                      
  |==============================================================                  |  77%
  |                                                                                      
  |==============================================================                  |  78%
  |                                                                                      
  |===============================================================                 |  78%
  |                                                                                      
  |===============================================================                 |  79%
  |                                                                                      
  |================================================================                |  80%
  |                                                                                      
  |=================================================================               |  81%
  |                                                                                      
  |=================================================================               |  82%
  |                                                                                      
  |==================================================================              |  82%
  |                                                                                      
  |==================================================================              |  83%
  |                                                                                      
  |===================================================================             |  83%
  |                                                                                      
  |===================================================================             |  84%
  |                                                                                      
  |====================================================================            |  85%
  |                                                                                      
  |=====================================================================           |  86%
  |                                                                                      
  |=====================================================================           |  87%
  |                                                                                      
  |======================================================================          |  87%
  |                                                                                      
  |======================================================================          |  88%
  |                                                                                      
  |=======================================================================         |  88%
  |                                                                                      
  |=======================================================================         |  89%
  |                                                                                      
  |========================================================================        |  89%
  |                                                                                      
  |========================================================================        |  90%
  |                                                                                      
  |=========================================================================       |  91%
  |                                                                                      
  |==========================================================================      |  92%
  |                                                                                      
  |==========================================================================      |  93%
  |                                                                                      
  |===========================================================================     |  93%
  |                                                                                      
  |===========================================================================     |  94%
  |                                                                                      
  |============================================================================    |  94%
  |                                                                                      
  |============================================================================    |  95%
  |                                                                                      
  |=============================================================================   |  96%
  |                                                                                      
  |==============================================================================  |  97%
  |                                                                                      
  |==============================================================================  |  98%
  |                                                                                      
  |=============================================================================== |  98%
  |                                                                                      
  |=============================================================================== |  99%
  |                                                                                      
  |================================================================================|  99%
  |                                                                                      
  |================================================================================| 100%
[1] "Scaling data matrix"

  |                                                                                      
  |                                                                                |   0%
  |                                                                                      
  |================================================================================| 100%
tiss <- FindVariableGenes(object = tiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.5)
Calculating gene means
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating gene variance to mean ratios
0%   10   20   30   40   50   60   70   80   90   100%
|----|----|----|----|----|----|----|----|----|----|
**************************************************|

Run Principal Component Analysis.

tiss <- RunPCA(object = tiss, do.print = FALSE)
tiss <- ProjectPCA(object = tiss, do.print = FALSE)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

PCElbowPlot(object = tiss)

Choose the number of principal components to use.

# Set number of principal components. 
n.pcs = 10

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

For the top-level clustering, aim to under-cluster instead of over-cluster. It will be easy to subset groups and further analyze them below.

# Set resolution 
res.used <- 0.5
tiss <- FindClusters(object = tiss, reduction.type = "pca", dims.use = 1:n.pcs, 
    resolution = res.used, print.output = 0, save.SNN = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
tiss <- RunTSNE(object = tiss, dims.use = 1:n.pcs, seed.use = 10, perplexity=30)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = tiss, do.label = T)

Check expression of genes of interset.

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

How big are the clusters?

table(tiss@ident)

  0   1   2   3   4   5 
127  84  54  47  35  17 

Which markers identify a specific cluster?

clust.markers <- FindMarkers(object = tiss, ident.1 = 0, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~14s          
   |++                                                | 2 % ~12s          
   |++                                                | 3 % ~12s          
   |+++                                               | 4 % ~11s          
   |+++                                               | 5 % ~11s          
   |++++                                              | 6 % ~10s          
   |++++                                              | 7 % ~10s          
   |+++++                                             | 8 % ~10s          
   |+++++                                             | 9 % ~10s          
   |++++++                                            | 10% ~10s          
   |++++++                                            | 11% ~10s          
   |+++++++                                           | 12% ~10s          
   |+++++++                                           | 13% ~10s          
   |++++++++                                          | 14% ~10s          
   |++++++++                                          | 15% ~10s          
   |+++++++++                                         | 16% ~09s          
   |+++++++++                                         | 17% ~09s          
   |++++++++++                                        | 18% ~09s          
   |++++++++++                                        | 19% ~09s          
   |+++++++++++                                       | 20% ~09s          
   |+++++++++++                                       | 21% ~09s          
   |++++++++++++                                      | 22% ~09s          
   |++++++++++++                                      | 23% ~08s          
   |+++++++++++++                                     | 24% ~08s          
   |+++++++++++++                                     | 26% ~08s          
   |++++++++++++++                                    | 27% ~08s          
   |++++++++++++++                                    | 28% ~08s          
   |+++++++++++++++                                   | 29% ~08s          
   |+++++++++++++++                                   | 30% ~08s          
   |++++++++++++++++                                  | 31% ~07s          
   |++++++++++++++++                                  | 32% ~07s          
   |+++++++++++++++++                                 | 33% ~07s          
   |+++++++++++++++++                                 | 34% ~07s          
   |++++++++++++++++++                                | 35% ~07s          
   |++++++++++++++++++                                | 36% ~07s          
   |+++++++++++++++++++                               | 37% ~07s          
   |+++++++++++++++++++                               | 38% ~07s          
   |++++++++++++++++++++                              | 39% ~06s          
   |++++++++++++++++++++                              | 40% ~06s          
   |+++++++++++++++++++++                             | 41% ~06s          
   |+++++++++++++++++++++                             | 42% ~06s          
   |++++++++++++++++++++++                            | 43% ~06s          
   |++++++++++++++++++++++                            | 44% ~06s          
   |+++++++++++++++++++++++                           | 45% ~06s          
   |+++++++++++++++++++++++                           | 46% ~06s          
   |++++++++++++++++++++++++                          | 47% ~06s          
   |++++++++++++++++++++++++                          | 48% ~06s          
   |+++++++++++++++++++++++++                         | 49% ~06s          
   |+++++++++++++++++++++++++                         | 50% ~05s          
   |++++++++++++++++++++++++++                        | 51% ~05s          
   |+++++++++++++++++++++++++++                       | 52% ~05s          
   |+++++++++++++++++++++++++++                       | 53% ~05s          
   |++++++++++++++++++++++++++++                      | 54% ~05s          
   |++++++++++++++++++++++++++++                      | 55% ~05s          
   |+++++++++++++++++++++++++++++                     | 56% ~05s          
   |+++++++++++++++++++++++++++++                     | 57% ~05s          
   |++++++++++++++++++++++++++++++                    | 58% ~05s          
   |++++++++++++++++++++++++++++++                    | 59% ~05s          
   |+++++++++++++++++++++++++++++++                   | 60% ~04s          
   |+++++++++++++++++++++++++++++++                   | 61% ~04s          
   |++++++++++++++++++++++++++++++++                  | 62% ~04s          
   |++++++++++++++++++++++++++++++++                  | 63% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~04s          
   |++++++++++++++++++++++++++++++++++                | 66% ~04s          
   |++++++++++++++++++++++++++++++++++                | 67% ~04s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~04s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~03s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~03s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~03s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 11s
print(x = head(x= clust.markers, n = 10))

You can also compute all markers for all clusters at once. This may take some time.

tiss.markers <- FindAllMarkers(object = tiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~12s          
   |+                                                 | 2 % ~11s          
   |++                                                | 3 % ~11s          
   |++                                                | 4 % ~11s          
   |+++                                               | 5 % ~11s          
   |+++                                               | 6 % ~11s          
   |++++                                              | 7 % ~11s          
   |++++                                              | 8 % ~10s          
   |+++++                                             | 9 % ~11s          
   |+++++                                             | 10% ~10s          
   |++++++                                            | 11% ~10s          
   |++++++                                            | 12% ~10s          
   |+++++++                                           | 13% ~10s          
   |+++++++                                           | 14% ~10s          
   |++++++++                                          | 15% ~10s          
   |++++++++                                          | 16% ~10s          
   |+++++++++                                         | 17% ~09s          
   |+++++++++                                         | 18% ~09s          
   |++++++++++                                        | 19% ~09s          
   |++++++++++                                        | 20% ~09s          
   |+++++++++++                                       | 21% ~09s          
   |+++++++++++                                       | 22% ~09s          
   |++++++++++++                                      | 23% ~09s          
   |++++++++++++                                      | 24% ~09s          
   |+++++++++++++                                     | 25% ~08s          
   |+++++++++++++                                     | 26% ~08s          
   |++++++++++++++                                    | 27% ~08s          
   |++++++++++++++                                    | 28% ~08s          
   |+++++++++++++++                                   | 29% ~08s          
   |+++++++++++++++                                   | 30% ~08s          
   |++++++++++++++++                                  | 31% ~08s          
   |++++++++++++++++                                  | 32% ~07s          
   |+++++++++++++++++                                 | 33% ~07s          
   |+++++++++++++++++                                | 34% ~07s          
   |++++++++++++++++++                                | 35% ~07s          
   |++++++++++++++++++                                | 36% ~07s          
   |+++++++++++++++++++                               | 37% ~07s          
   |+++++++++++++++++++                               | 38% ~07s          
   |++++++++++++++++++++                              | 39% ~07s          
   |++++++++++++++++++++                              | 40% ~07s          
   |+++++++++++++++++++++                             | 41% ~06s          
   |+++++++++++++++++++++                             | 42% ~06s          
   |++++++++++++++++++++++                            | 43% ~06s          
   |++++++++++++++++++++++                            | 44% ~06s          
   |+++++++++++++++++++++++                           | 45% ~06s          
   |+++++++++++++++++++++++                           | 46% ~06s          
   |++++++++++++++++++++++++                          | 47% ~06s          
   |++++++++++++++++++++++++                          | 48% ~06s          
   |+++++++++++++++++++++++++                         | 49% ~06s          
   |+++++++++++++++++++++++++                         | 50% ~06s          
   |++++++++++++++++++++++++++                        | 51% ~05s          
   |++++++++++++++++++++++++++                        | 52% ~05s          
   |+++++++++++++++++++++++++++                       | 53% ~05s          
   |+++++++++++++++++++++++++++                       | 54% ~05s          
   |++++++++++++++++++++++++++++                      | 55% ~05s          
   |++++++++++++++++++++++++++++                     | 56% ~05s          
   |+++++++++++++++++++++++++++++                     | 57% ~05s          
   |+++++++++++++++++++++++++++++                     | 58% ~05s          
   |++++++++++++++++++++++++++++++                    | 59% ~05s          
   |++++++++++++++++++++++++++++++                    | 60% ~04s          
   |+++++++++++++++++++++++++++++++                   | 61% ~04s          
   |+++++++++++++++++++++++++++++++                   | 62% ~04s          
   |++++++++++++++++++++++++++++++++                  | 63% ~04s          
   |++++++++++++++++++++++++++++++++                  | 64% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~04s          
   |++++++++++++++++++++++++++++++++++                | 67% ~04s          
   |++++++++++++++++++++++++++++++++++               | 68% ~04s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~03s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~03s          
   |+++++++++++++++++++++++++++++++++++++++          | 78% ~03s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
   |++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 11s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~07s          
   |++                                                | 2 % ~07s          
   |++                                                | 3 % ~06s          
   |+++                                               | 4 % ~07s          
   |+++                                               | 5 % ~06s          
   |++++                                              | 6 % ~06s          
   |++++                                              | 7 % ~06s          
   |+++++                                             | 9 % ~06s          
   |+++++                                             | 10% ~06s          
   |++++++                                            | 11% ~06s          
   |++++++                                            | 12% ~06s          
   |+++++++                                           | 13% ~06s          
   |+++++++                                           | 14% ~06s          
   |++++++++                                          | 15% ~06s          
   |++++++++                                          | 16% ~06s          
   |+++++++++                                         | 17% ~06s          
   |++++++++++                                        | 18% ~06s          
   |++++++++++                                        | 19% ~06s          
   |+++++++++++                                       | 20% ~06s          
   |+++++++++++                                       | 21% ~06s          
   |++++++++++++                                      | 22% ~06s          
   |++++++++++++                                      | 23% ~06s          
   |+++++++++++++                                     | 24% ~06s          
   |+++++++++++++                                     | 26% ~06s          
   |++++++++++++++                                    | 27% ~06s          
   |++++++++++++++                                    | 28% ~06s          
   |+++++++++++++++                                   | 29% ~05s          
   |+++++++++++++++                                   | 30% ~05s          
   |++++++++++++++++                                  | 31% ~05s          
   |++++++++++++++++                                  | 32% ~05s          
   |+++++++++++++++++                                 | 33% ~05s          
   |++++++++++++++++++                                | 34% ~05s          
   |++++++++++++++++++                                | 35% ~05s          
   |+++++++++++++++++++                               | 36% ~05s          
   |+++++++++++++++++++                               | 37% ~05s          
   |++++++++++++++++++++                              | 38% ~05s          
   |++++++++++++++++++++                              | 39% ~05s          
   |+++++++++++++++++++++                             | 40% ~05s          
   |+++++++++++++++++++++                             | 41% ~05s          
   |++++++++++++++++++++++                            | 43% ~05s          
   |++++++++++++++++++++++                            | 44% ~04s          
   |+++++++++++++++++++++++                           | 45% ~04s          
   |+++++++++++++++++++++++                           | 46% ~04s          
   |++++++++++++++++++++++++                          | 47% ~04s          
   |++++++++++++++++++++++++                          | 48% ~04s          
   |+++++++++++++++++++++++++                         | 49% ~04s          
   |+++++++++++++++++++++++++                         | 50% ~04s          
   |++++++++++++++++++++++++++                        | 51% ~04s          
   |+++++++++++++++++++++++++++                       | 52% ~04s          
   |+++++++++++++++++++++++++++                       | 53% ~04s          
   |++++++++++++++++++++++++++++                      | 54% ~04s          
   |++++++++++++++++++++++++++++                      | 55% ~04s          
   |+++++++++++++++++++++++++++++                     | 56% ~03s          
   |+++++++++++++++++++++++++++++                     | 57% ~03s          
   |++++++++++++++++++++++++++++++                    | 59% ~03s          
   |++++++++++++++++++++++++++++++                    | 60% ~03s          
   |+++++++++++++++++++++++++++++++                   | 61% ~03s          
   |+++++++++++++++++++++++++++++++                   | 62% ~03s          
   |++++++++++++++++++++++++++++++++                  | 63% ~03s          
   |++++++++++++++++++++++++++++++++                  | 64% ~03s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
   |++++++++++++++++++++++++++++++++++                | 67% ~03s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~03s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~02s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 08s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~09s          
   |++                                                | 2 % ~08s          
   |++                                                | 3 % ~07s          
   |+++                                               | 4 % ~07s          
   |+++                                               | 5 % ~06s          
   |++++                                              | 6 % ~06s          
   |++++                                              | 7 % ~06s          
   |+++++                                             | 9 % ~06s          
   |+++++                                             | 10% ~06s          
   |++++++                                            | 11% ~06s          
   |++++++                                            | 12% ~06s          
   |+++++++                                           | 13% ~06s          
   |+++++++                                           | 14% ~06s          
   |++++++++                                          | 15% ~06s          
   |++++++++                                          | 16% ~05s          
   |+++++++++                                         | 17% ~05s          
   |++++++++++                                        | 18% ~05s          
   |++++++++++                                        | 19% ~05s          
   |+++++++++++                                       | 20% ~05s          
   |+++++++++++                                       | 21% ~05s          
   |++++++++++++                                      | 22% ~05s          
   |++++++++++++                                      | 23% ~05s          
   |+++++++++++++                                     | 24% ~05s          
   |+++++++++++++                                     | 26% ~05s          
   |++++++++++++++                                    | 27% ~05s          
   |++++++++++++++                                    | 28% ~05s          
   |+++++++++++++++                                   | 29% ~05s          
   |+++++++++++++++                                   | 30% ~05s          
   |++++++++++++++++                                  | 31% ~05s          
   |++++++++++++++++                                  | 32% ~04s          
   |+++++++++++++++++                                 | 33% ~04s          
   |++++++++++++++++++                                | 34% ~04s          
   |++++++++++++++++++                                | 35% ~04s          
   |+++++++++++++++++++                               | 36% ~04s          
   |+++++++++++++++++++                               | 37% ~04s          
   |++++++++++++++++++++                              | 38% ~04s          
   |++++++++++++++++++++                              | 39% ~04s          
   |+++++++++++++++++++++                             | 40% ~04s          
   |+++++++++++++++++++++                             | 41% ~04s          
   |++++++++++++++++++++++                            | 43% ~04s          
   |++++++++++++++++++++++                            | 44% ~04s          
   |+++++++++++++++++++++++                           | 45% ~04s          
   |+++++++++++++++++++++++                           | 46% ~04s          
   |++++++++++++++++++++++++                          | 47% ~04s          
   |++++++++++++++++++++++++                          | 48% ~03s          
   |+++++++++++++++++++++++++                         | 49% ~03s          
   |+++++++++++++++++++++++++                         | 50% ~03s          
   |++++++++++++++++++++++++++                        | 51% ~03s          
   |+++++++++++++++++++++++++++                       | 52% ~03s          
   |+++++++++++++++++++++++++++                       | 53% ~03s          
   |++++++++++++++++++++++++++++                      | 54% ~03s          
   |++++++++++++++++++++++++++++                      | 55% ~03s          
   |+++++++++++++++++++++++++++++                     | 56% ~03s          
   |+++++++++++++++++++++++++++++                     | 57% ~03s          
   |++++++++++++++++++++++++++++++                    | 59% ~03s          
   |++++++++++++++++++++++++++++++                    | 60% ~03s          
   |+++++++++++++++++++++++++++++++                   | 61% ~03s          
   |+++++++++++++++++++++++++++++++                   | 62% ~03s          
   |++++++++++++++++++++++++++++++++                  | 63% ~03s          
   |++++++++++++++++++++++++++++++++                  | 64% ~02s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~02s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~02s          
   |++++++++++++++++++++++++++++++++++                | 67% ~02s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~02s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~02s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 07s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~08s          
   |++                                                | 2 % ~08s          
   |++                                                | 3 % ~07s          
   |+++                                               | 4 % ~07s          
   |+++                                               | 5 % ~08s          
   |++++                                              | 6 % ~07s          
   |++++                                              | 7 % ~07s          
   |+++++                                             | 8 % ~07s          
   |+++++                                             | 9 % ~07s          
   |++++++                                            | 10% ~07s          
   |++++++                                            | 11% ~07s          
   |+++++++                                           | 12% ~06s          
   |+++++++                                           | 13% ~06s          
   |++++++++                                          | 14% ~06s          
   |++++++++                                          | 15% ~06s          
   |+++++++++                                         | 16% ~06s          
   |+++++++++                                         | 17% ~06s          
   |++++++++++                                        | 18% ~06s          
   |++++++++++                                        | 19% ~06s          
   |+++++++++++                                       | 20% ~06s          
   |+++++++++++                                       | 21% ~06s          
   |++++++++++++                                      | 22% ~06s          
   |++++++++++++                                      | 23% ~05s          
   |+++++++++++++                                     | 24% ~05s          
   |+++++++++++++                                     | 25% ~05s          
   |++++++++++++++                                    | 26% ~05s          
   |++++++++++++++                                    | 27% ~05s          
   |+++++++++++++++                                   | 28% ~05s          
   |+++++++++++++++                                   | 29% ~05s          
   |++++++++++++++++                                  | 30% ~05s          
   |++++++++++++++++                                  | 31% ~05s          
   |+++++++++++++++++                                 | 32% ~05s          
   |+++++++++++++++++                                 | 33% ~05s          
   |++++++++++++++++++                                | 34% ~05s          
   |++++++++++++++++++                                | 35% ~05s          
   |+++++++++++++++++++                               | 36% ~05s          
   |+++++++++++++++++++                               | 37% ~04s          
   |++++++++++++++++++++                              | 38% ~04s          
   |++++++++++++++++++++                              | 39% ~04s          
   |+++++++++++++++++++++                             | 40% ~04s          
   |+++++++++++++++++++++                             | 41% ~04s          
   |++++++++++++++++++++++                            | 42% ~04s          
   |++++++++++++++++++++++                            | 43% ~04s          
   |+++++++++++++++++++++++                           | 44% ~04s          
   |+++++++++++++++++++++++                           | 45% ~04s          
   |++++++++++++++++++++++++                          | 46% ~04s          
   |++++++++++++++++++++++++                          | 47% ~04s          
   |+++++++++++++++++++++++++                         | 48% ~04s          
   |+++++++++++++++++++++++++                         | 49% ~04s          
   |++++++++++++++++++++++++++                        | 51% ~03s          
   |++++++++++++++++++++++++++                        | 52% ~03s          
   |+++++++++++++++++++++++++++                       | 53% ~03s          
   |+++++++++++++++++++++++++++                       | 54% ~03s          
   |++++++++++++++++++++++++++++                      | 55% ~03s          
   |++++++++++++++++++++++++++++                      | 56% ~03s          
   |+++++++++++++++++++++++++++++                     | 57% ~03s          
   |+++++++++++++++++++++++++++++                     | 58% ~03s          
   |++++++++++++++++++++++++++++++                    | 59% ~03s          
   |++++++++++++++++++++++++++++++                    | 60% ~03s          
   |+++++++++++++++++++++++++++++++                   | 61% ~03s          
   |+++++++++++++++++++++++++++++++                   | 62% ~03s          
   |++++++++++++++++++++++++++++++++                  | 63% ~03s          
   |++++++++++++++++++++++++++++++++                  | 64% ~03s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~02s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~02s          
   |++++++++++++++++++++++++++++++++++                | 67% ~02s          
   |++++++++++++++++++++++++++++++++++                | 68% ~02s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~02s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~02s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~02s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~01s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 07s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~10s          
   |++                                                | 2 % ~09s          
   |++                                                | 3 % ~09s          
   |+++                                               | 4 % ~09s          
   |+++                                               | 5 % ~08s          
   |++++                                              | 6 % ~08s          
   |++++                                              | 7 % ~08s          
   |+++++                                             | 8 % ~08s          
   |+++++                                             | 9 % ~08s          
   |++++++                                            | 10% ~08s          
   |++++++                                            | 11% ~08s          
   |+++++++                                           | 12% ~08s          
   |+++++++                                           | 13% ~08s          
   |++++++++                                          | 14% ~08s          
   |++++++++                                          | 15% ~08s          
   |+++++++++                                         | 16% ~08s          
   |+++++++++                                         | 18% ~08s          
   |++++++++++                                        | 19% ~07s          
   |++++++++++                                        | 20% ~07s          
   |+++++++++++                                       | 21% ~07s          
   |+++++++++++                                       | 22% ~07s          
   |++++++++++++                                      | 23% ~07s          
   |++++++++++++                                      | 24% ~07s          
   |+++++++++++++                                     | 25% ~07s          
   |+++++++++++++                                     | 26% ~07s          
   |++++++++++++++                                    | 27% ~07s          
   |++++++++++++++                                    | 28% ~07s          
   |+++++++++++++++                                   | 29% ~07s          
   |+++++++++++++++                                   | 30% ~07s          
   |++++++++++++++++                                  | 31% ~07s          
   |++++++++++++++++                                  | 32% ~07s          
   |+++++++++++++++++                                 | 33% ~06s          
   |++++++++++++++++++                                | 34% ~06s          
   |++++++++++++++++++                                | 35% ~06s          
   |+++++++++++++++++++                               | 36% ~06s          
   |+++++++++++++++++++                               | 37% ~06s          
   |++++++++++++++++++++                              | 38% ~06s          
   |++++++++++++++++++++                              | 39% ~06s          
   |+++++++++++++++++++++                             | 40% ~06s          
   |+++++++++++++++++++++                             | 41% ~06s          
   |++++++++++++++++++++++                            | 42% ~06s          
   |++++++++++++++++++++++                            | 43% ~05s          
   |+++++++++++++++++++++++                           | 44% ~05s          
   |+++++++++++++++++++++++                           | 45% ~05s          
   |++++++++++++++++++++++++                          | 46% ~05s          
   |++++++++++++++++++++++++                          | 47% ~05s          
   |+++++++++++++++++++++++++                         | 48% ~05s          
   |+++++++++++++++++++++++++                         | 49% ~05s          
   |++++++++++++++++++++++++++                        | 51% ~05s          
   |++++++++++++++++++++++++++                        | 52% ~05s          
   |+++++++++++++++++++++++++++                       | 53% ~05s          
   |+++++++++++++++++++++++++++                       | 54% ~05s          
   |++++++++++++++++++++++++++++                      | 55% ~05s          
   |++++++++++++++++++++++++++++                      | 56% ~04s          
   |+++++++++++++++++++++++++++++                     | 57% ~04s          
   |+++++++++++++++++++++++++++++                     | 58% ~04s          
   |++++++++++++++++++++++++++++++                    | 59% ~04s          
   |++++++++++++++++++++++++++++++                    | 60% ~04s          
   |+++++++++++++++++++++++++++++++                   | 61% ~04s          
   |+++++++++++++++++++++++++++++++                   | 62% ~04s          
   |++++++++++++++++++++++++++++++++                  | 63% ~04s          
   |++++++++++++++++++++++++++++++++                  | 64% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
   |++++++++++++++++++++++++++++++++++                | 67% ~03s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~03s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~02s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 10s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~12s          
   |++                                                | 2 % ~13s          
   |++                                                | 3 % ~12s          
   |+++                                               | 4 % ~12s          
   |+++                                               | 5 % ~11s          
   |++++                                              | 6 % ~11s          
   |++++                                              | 7 % ~10s          
   |+++++                                             | 8 % ~10s          
   |+++++                                             | 9 % ~10s          
   |++++++                                            | 10% ~10s          
   |++++++                                            | 11% ~10s          
   |+++++++                                           | 12% ~10s          
   |+++++++                                           | 13% ~10s          
   |++++++++                                          | 14% ~10s          
   |++++++++                                          | 15% ~10s          
   |+++++++++                                         | 16% ~10s          
   |+++++++++                                         | 17% ~09s          
   |++++++++++                                        | 18% ~09s          
   |++++++++++                                        | 19% ~09s          
   |+++++++++++                                       | 20% ~09s          
   |+++++++++++                                       | 21% ~09s          
   |++++++++++++                                      | 22% ~09s          
   |++++++++++++                                      | 23% ~09s          
   |+++++++++++++                                     | 24% ~09s          
   |+++++++++++++                                     | 26% ~09s          
   |++++++++++++++                                    | 27% ~08s          
   |++++++++++++++                                    | 28% ~08s          
   |+++++++++++++++                                   | 29% ~08s          
   |+++++++++++++++                                   | 30% ~08s          
   |++++++++++++++++                                  | 31% ~08s          
   |++++++++++++++++                                  | 32% ~08s          
   |+++++++++++++++++                                 | 33% ~08s          
   |+++++++++++++++++                                 | 34% ~08s          
   |++++++++++++++++++                                | 35% ~07s          
   |++++++++++++++++++                                | 36% ~07s          
   |+++++++++++++++++++                               | 37% ~07s          
   |+++++++++++++++++++                               | 38% ~07s          
   |++++++++++++++++++++                              | 39% ~07s          
   |++++++++++++++++++++                              | 40% ~07s          
   |+++++++++++++++++++++                             | 41% ~07s          
   |+++++++++++++++++++++                             | 42% ~07s          
   |++++++++++++++++++++++                            | 43% ~06s          
   |++++++++++++++++++++++                            | 44% ~06s          
   |+++++++++++++++++++++++                           | 45% ~06s          
   |+++++++++++++++++++++++                           | 46% ~06s          
   |++++++++++++++++++++++++                          | 47% ~06s          
   |++++++++++++++++++++++++                          | 48% ~06s          
   |+++++++++++++++++++++++++                         | 49% ~06s          
   |+++++++++++++++++++++++++                         | 50% ~06s          
   |++++++++++++++++++++++++++                        | 51% ~05s          
   |+++++++++++++++++++++++++++                       | 52% ~05s          
   |+++++++++++++++++++++++++++                       | 53% ~05s          
   |++++++++++++++++++++++++++++                      | 54% ~05s          
   |++++++++++++++++++++++++++++                      | 55% ~05s          
   |+++++++++++++++++++++++++++++                     | 56% ~05s          
   |+++++++++++++++++++++++++++++                     | 57% ~05s          
   |++++++++++++++++++++++++++++++                    | 58% ~05s          
   |++++++++++++++++++++++++++++++                    | 59% ~05s          
   |+++++++++++++++++++++++++++++++                   | 60% ~04s          
   |+++++++++++++++++++++++++++++++                   | 61% ~04s          
   |++++++++++++++++++++++++++++++++                  | 62% ~04s          
   |++++++++++++++++++++++++++++++++                  | 63% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~04s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~04s          
   |++++++++++++++++++++++++++++++++++                | 66% ~04s          
   |++++++++++++++++++++++++++++++++++                | 67% ~04s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~04s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~03s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~03s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~03s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~03s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~03s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~02s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 11s

Display the top markers you computed above.

tiss.markers %>% group_by(cluster) %>% top_n(5, avg_diff)

Assigning cell type identity to clusters

At a coarse level, we can use canonical markers to match the unbiased clustering to known cell types:

0: heterogenous group of cells 1: endothelial cells 2: adipocytes 3: endothelial cells 4: fibroblasts 5: hematopoetic

# stash current cluster IDs
tiss <- StashIdent(object = tiss, save.name = "cluster.ids")
# enumerate current cluster IDs and the labels for them
cluster.ids <- c(0, 1, 2, 3, 4, 5)
annotation <- c("heterogenous group of cells", "endothelial cell", "epicardial adipocytes", "endothelial cells", "fibroblasts", "hematopoetic cells")
tiss@meta.data[,'annotation'] <- plyr::mapvalues(x = tiss@meta.data$cluster.ids, from = cluster.ids, to = annotation)
TSNEPlot(object = tiss, do.label = TRUE, pt.size = 0.5, group.by='annotation')

Checking for batch effects

head(tiss@meta.data)

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = tiss, do.return = TRUE, group.by = "plate.barcode")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(tiss@ident), as.character(tiss@meta.data$plate.barcode))
   
    B002430 B002431 MAA000594 MAA000595 MAA000906 MAA000908
  0       5      16        65        25        12         4
  1       0       0         1         2         3        78
  2      12      38         1         1         2         0
  3       2       1         0         0        33        11
  4       0       0        17        17         1         0
  5       0       0         2        15         0         0

Subset and iterate

We can repeat the above analysis on a subset of cells, defined using cluster IDs or some other metadata. This is a good way to drill down and find substructure.

First subset

rr # Subset data based on cluster id subtiss <- SubsetData(object = tiss, ident.use = c(0), do.center = F, do.scale = F, cells.use = )

To subset data based on annotation or other metadata, you can explicitly pass cell names

anno = ‘thymocyte’

cells.to.use = tiss@cell.names[which(tiss@meta.data$annotation == anno)]

subtiss <- SubsetData(object = tiss, cells.use = cells.to.use, do.center = F, do.scale = F)

rr subtiss <- FindVariableGenes(object = subtiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.8) subtiss <- RunPCA(object = subtiss, pcs.compute = 20) subtiss <- ProjectPCA(object = subtiss, do.print = FALSE)

Run Principal Component Analysis.

rr subtiss <- RunPCA(object = subtiss, do.print = FALSE) subtiss <- ProjectPCA(object = subtiss, do.print = FALSE)

rr # If this fails for your subset, it may be that cells.use is more cells than you have left! Try reducing it. PCHeatmap(object = subtiss, pc.use = 1:3, cells.use = 200, do.balanced = TRUE, label.columns = FALSE, num.genes = 12)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

rr PCElbowPlot(object = subtiss)

Choose the number of principal components to use.

rr # Set number of principal components. sub.n.pcs = 10

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

To visualize

rr # If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10). subtiss <- RunTSNE(object = subtiss, dims.use = 1:sub.n.pcs, seed.use = 10, perplexity=10)

rr # note that you can set do.label=T to help label individual clusters TSNEPlot(object = subtiss, do.label = T)

rr subtiss.markers <- FindAllMarkers(object = subtiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

rr subtiss.markers %>% group_by(cluster) %>% top_n(6, avg_diff)

Check expression of genes of interset.

rr genes_to_check = (subtiss.markers %>% group_by(cluster) %>% top_n(6, avg_diff))$gene # genes_to_check = c(‘Vim’,‘Krt5’,‘Krt8’,‘Ptprc’,‘Epcam’,‘H2-D1’,‘H2-Aa’,‘H2-Ab1’,‘Cd34’,‘Itgam’,‘Syk’,‘Col1a2’,‘Timp2’,‘Cd74’,‘Laptm5’,‘Selplg’,‘Fabp4’,‘Icam1’,‘Vcam1’,‘Adipor1’,‘Alas2’,‘Cnn1’,‘Acta2’,‘Dcn’,‘Myocd’,‘Mmp2’,‘Lmna’,‘Eln’,‘Col3a1’,‘Col4a1’,‘Col1a1’,‘Pdgfra’,‘Gypa’,‘Col6a3’,‘Pecam1’,‘Pdgfrb’,‘Psmb8’,‘Myh10’,‘Tpm4’,‘Cald1’,‘Rbp1’, ‘Cd36’)

FeaturePlot(subtiss, genes_to_check, pt.size = 1)

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

How big are the clusters?

rr table(subtiss@ident)

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

Print a table showing the count of cells in each identity category from each plate.

rr table(as.character(subtiss@ident), as.character(subtiss@meta.data$plate.barcode))

Assigning subannotations

For the subsets, we produce subannotations. These will be written back as metadata in the original object, so we can see all subannotations together.

If some of the clusters you find in the subset deserve additional annotation, you can add that right here. Use NA for clusters for which no subannotation is needed.

Save the tissue object with updated annotations

filename = here('00_data_ingest', 'tissue_seurat_robj', 
                     paste0(tissue_of_interest, "_seurat_tiss.Robj"))
print(filename)
save(tiss, file=filename)

Export the final metadata

So that Biohub can easily combine all your annotations, please export them as a simple csv.

LS0tCnRpdGxlOiAiTUFDQSBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKRW50ZXIgdGhlIGRpcmVjdG9yeSBvZiB0aGUgbWFjYSBmb2xkZXIgb24geW91ciBkcml2ZSBhbmQgdGhlIG5hbWUgb2YgdGhlIHRpc3N1ZSB5b3Ugd2FudCB0byBhbmFseXplLgoKYGBge3J9CnRpc3N1ZV9vZl9pbnRlcmVzdCA9ICJBb3J0YSIKYGBgCgpMb2FkIHRoZSByZXF1aXNpdGUgcGFja2FnZXMgYW5kIHNvbWUgYWRkaXRpb25hbCBoZWxwZXIgZnVuY3Rpb25zLgoKYGBge3J9CmxpYnJhcnkoaGVyZSkKbGlicmFyeSh1c2VmdWwpCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KE1hdHJpeCkKCnNhdmVfZGlyID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAndGlzc3VlX3JvYmonKQpgYGAKCkxvYWQgdGhlIHBsYXRlIG1ldGFkYXRhLiBDaGVjayB3aGljaCBwbGF0ZXMgaGF2ZSBiZWVuIGRvd25sb2FkZWQuCgpgYGB7cn0KcGxhdGVfbWV0YWRhdGFfZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICdmYWNzX3Jhd19kYXRhJywgJ21ldGFkYXRhX0ZBQ1MuY3N2JykKCnBsYXRlX21ldGFkYXRhIDwtIHJlYWQuY3N2KHBsYXRlX21ldGFkYXRhX2ZpbGVuYW1lLCBzZXA9IiwiLCBoZWFkZXIgPSBUUlVFKQpjb2xuYW1lcyhwbGF0ZV9tZXRhZGF0YSlbMV0gPC0gInBsYXRlLmJhcmNvZGUiCnBsYXRlX21ldGFkYXRhCiMgY291bnRfZmlsZXMgPSBsaXN0LmZpbGVzKHBhc3RlMChyb290ZGlyLCAiL2RhdGEvcGxhdGVzIiksIHBhdHRlcm4gPSAiKmNvdW50cy50YWIiLHJlY3Vyc2l2ZSA9IEZBTFNFKQojIGRvd25sb2FkZWRfcGxhdGVzID0gbGFwcGx5KGNvdW50X2ZpbGVzLCBmdW5jdGlvbih4KSBzdHJzcGxpdCh4LCJbLi9dIilbWzFdXVsxXSkKIyBwbGF0ZV9tZXRhZGF0YSA9IHBsYXRlX21ldGFkYXRhW3BsYXRlX21ldGFkYXRhJHBsYXRlLmJhcmNvZGUgJWluJSBkb3dubG9hZGVkX3BsYXRlcyxdCiMgCiMgc2F2ZV9kaXIgPSBwYXN0ZTAocm9vdGRpciwgJy9zYXZlJykKIyBkaXIuY3JlYXRlKHNhdmVfZGlyKQpgYGAKCiJBb3J0YSIgaXMgYSBzdWJ0aXNzdWUgb2YgIkhlYXJ0IiBhbmQgd2Ugd2lsbCBoYXZlIHRvIGZpbHRlciBmb3IgdGhpcy4KCmBgYHtyfQp0aXNzdWVfcGxhdGVzID0gZmlsdGVyKHBsYXRlX21ldGFkYXRhLCBzdWJ0aXNzdWUgPT0gdGlzc3VlX29mX2ludGVyZXN0KVssYygncGxhdGUuYmFyY29kZScsJ3Rpc3N1ZScsJ3N1YnRpc3N1ZScsJ21vdXNlLnNleCcpXQp0aXNzdWVfcGxhdGVzCmBgYApMb2FkIHRoZSByZWFkIGNvdW50IGRhdGEuCmBgYHtyfQojTG9hZCB0aGUgZ2VuZSBuYW1lcyBhbmQgc2V0IHRoZSBtZXRhZGF0YSBjb2x1bW5zIGJ5IG9wZW5pbmcgdGhlIGZpcnN0IGZpbGUKZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICdmYWNzX3Jhd19kYXRhJywgJ0ZBQ1MnLCAnSGVhcnQtY291bnRzLmNzdicpCgpyYXcuZGF0YSA9IHJlYWQuY3N2KGZpbGVuYW1lLCBzZXA9IiwiLCByb3cubmFtZXM9MSkKIyByYXcuZGF0YSA9IGRhdGEuZnJhbWUocm93Lm5hbWVzID0gcm93bmFtZXMocmF3LmRhdGEpKQpjb3JuZXIocmF3LmRhdGEpCmBgYAoKVXNlIG9ubHkgY2VsbHMgZnJvbSAiQW9ydGEiIiBwbGF0ZSBiYXJjb2Rlcy4KCmBgYHtyfQpwbGF0ZS5iYXJjb2RlcyA9IGxhcHBseShjb2xuYW1lcyhyYXcuZGF0YSksIGZ1bmN0aW9uKHgpIHN0cnNwbGl0KHN0cnNwbGl0KHgsICJfIilbWzFdXVsxXSwgJy4nLCBmaXhlZD1UUlVFKVtbMV1dWzJdKQpoZWFkKHBsYXRlLmJhcmNvZGVzKQpgYGAKCmBgYHtyfQphb3J0YS5wbGF0ZXMgPSBmaWx0ZXIodGlzc3VlX3BsYXRlcywgc3VidGlzc3VlID09ICJBb3J0YSIpCmFvcnRhLmJhcmNvZGVzID0gcGxhdGUuYmFyY29kZXMgJWluJSBhb3J0YS5wbGF0ZXMkcGxhdGUuYmFyY29kZQpzdW0oYW9ydGEuYmFyY29kZXMpCmBgYApVc2Ugb25seSB0aGUgYW9ydGEgYmFyY29kZXMKYGBge3J9CnJhdy5kYXRhID0gcmF3LmRhdGFbYW9ydGEuYmFyY29kZXNdCmBgYAoKCmBgYHtyfQptZXRhLmRhdGEgPSBwbGF0ZV9tZXRhZGF0YVtwbGF0ZV9tZXRhZGF0YSRwbGF0ZS5iYXJjb2RlICVpbiUgcGxhdGUuYmFyY29kZXMsIF0KZGltKHBsYXRlX21ldGFkYXRhKQpkaW0obWV0YS5kYXRhKQpjb3JuZXIobWV0YS5kYXRhKQpgYGAKCmBgYHtyfQpiYXJjb2RlLmRmID0gdC5kYXRhLmZyYW1lKGFzLmRhdGEuZnJhbWUocGxhdGUuYmFyY29kZXNbYW9ydGEuYmFyY29kZXNdKSkKaGVhZChiYXJjb2RlLmRmKQpgYGAKYGBge3J9CmRpbShyYXcuZGF0YSkKYGBgCgoKYGBge3J9CnJvd25hbWVzKGJhcmNvZGUuZGYpID0gY29sbmFtZXMocmF3LmRhdGEpCmNvbG5hbWVzKGJhcmNvZGUuZGYpID0gYygncGxhdGUuYmFyY29kZScpCmhlYWQoYmFyY29kZS5kZikKYGBgCmBgYHtyfQpoZWFkKHBsYXRlX21ldGFkYXRhKQpgYGAKCgpgYGB7cn0Kcm5hbWVzID0gcm93Lm5hbWVzKGJhcmNvZGUuZGYpCm1ldGEuZGF0YSA8LSBtZXJnZShiYXJjb2RlLmRmLCBwbGF0ZV9tZXRhZGF0YSwgYnk9J3BsYXRlLmJhcmNvZGUnLCBzb3J0ID0gRikKcm93Lm5hbWVzKG1ldGEuZGF0YSkgPC0gcm5hbWVzCmhlYWQobWV0YS5kYXRhKQpgYGAKCgpQcm9jZXNzIHRoZSByYXcgZGF0YSBhbmQgbG9hZCBpdCBpbnRvIHRoZSBTZXVyYXQgb2JqZWN0LgoKYGBge3J9CiMgRmluZCBFUkNDJ3MsIGNvbXB1dGUgdGhlIHBlcmNlbnQgRVJDQywgYW5kIGRyb3AgdGhlbSBmcm9tIHRoZSByYXcgZGF0YS4KZXJjY3MgPC0gZ3JlcChwYXR0ZXJuID0gIl5FUkNDLSIsIHggPSByb3duYW1lcyh4ID0gcmF3LmRhdGEpLCB2YWx1ZSA9IFRSVUUpCnBlcmNlbnQuZXJjYyA8LSBNYXRyaXg6OmNvbFN1bXMocmF3LmRhdGFbZXJjY3MsIF0pL01hdHJpeDo6Y29sU3VtcyhyYXcuZGF0YSkKZXJjYy5pbmRleCA8LSBncmVwKHBhdHRlcm4gPSAiXkVSQ0MtIiwgeCA9IHJvd25hbWVzKHggPSByYXcuZGF0YSksIHZhbHVlID0gRkFMU0UpCnJhdy5kYXRhIDwtIHJhdy5kYXRhWy1lcmNjLmluZGV4LF0KCiMgQ3JlYXRlIHRoZSBTZXVyYXQgb2JqZWN0IHdpdGggYWxsIHRoZSBkYXRhCnRpc3MgPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KHJhdy5kYXRhID0gcmF3LmRhdGEsIHByb2plY3QgPSB0aXNzdWVfb2ZfaW50ZXJlc3QsIAogICAgICAgICAgICAgICAgICAgIG1pbi5jZWxscyA9IDUsIG1pbi5nZW5lcyA9IDUpCgp0aXNzIDwtIEFkZE1ldGFEYXRhKG9iamVjdCA9IHRpc3MsIG1ldGEuZGF0YSkKdGlzcyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSB0aXNzLCBwZXJjZW50LmVyY2MsIGNvbC5uYW1lID0gInBlcmNlbnQuZXJjYyIpCiMgQ2hhbmdlIGRlZmF1bHQgbmFtZSBmb3Igc3VtcyBvZiBjb3VudHMgZnJvbSBuVU1JIHRvIG5SZWFkcwpjb2xuYW1lcyh0aXNzQG1ldGEuZGF0YSlbY29sbmFtZXModGlzc0BtZXRhLmRhdGEpID09ICduVU1JJ10gPC0gJ25SZWFkcycKCiMgQ3JlYXRlIG1ldGFkYXRhIGNvbHVtbnMgZm9yIGFubm90YXRpb25zIGFuZCBzdWJhbm5vdGF0aW9ucwp0aXNzQG1ldGEuZGF0YVssJ2Fubm90YXRpb24nXSA8LSBOQQp0aXNzQG1ldGEuZGF0YVssJ3N1YmFubm90YXRpb24nXSA8LSBOQQpgYGAKCgpDYWxjdWxhdGUgcGVyY2VudCByaWJvc29tYWwgZ2VuZXMuCgpgYGB7cn0Kcmliby5nZW5lcyA8LSBncmVwKHBhdHRlcm4gPSAiXlJwW3NsXVtbOmRpZ2l0Ol1dIiwgeCA9IHJvd25hbWVzKHggPSB0aXNzQGRhdGEpLCB2YWx1ZSA9IFRSVUUpCnBlcmNlbnQucmlibyA8LSBNYXRyaXg6OmNvbFN1bXModGlzc0ByYXcuZGF0YVtyaWJvLmdlbmVzLCBdKS9NYXRyaXg6OmNvbFN1bXModGlzc0ByYXcuZGF0YSkKdGlzcyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSB0aXNzLCBtZXRhZGF0YSA9IHBlcmNlbnQucmlibywgY29sLm5hbWUgPSAicGVyY2VudC5yaWJvIikKYGBgCgpBIHNhbml0eSBjaGVjazogZ2VuZXMgcGVyIGNlbGwgdnMgcmVhZHMgcGVyIGNlbGwuCgpgYGB7cn0KR2VuZVBsb3Qob2JqZWN0ID0gdGlzcywgZ2VuZTEgPSAiblJlYWRzIiwgZ2VuZTIgPSAibkdlbmUiLCB1c2UucmF3PVQpCmBgYAoKRmlsdGVyIG91dCBjZWxscyB3aXRoIGZldyByZWFkcyBhbmQgZmV3IGdlbmVzLgoKYGBge3J9CnRpc3MgPC0gRmlsdGVyQ2VsbHMob2JqZWN0ID0gdGlzcywgc3Vic2V0Lm5hbWVzID0gYygibkdlbmUiLCAiblJlYWRzIiksIAogICAgbG93LnRocmVzaG9sZHMgPSBjKDUwMCwgNTAwMDApLCBoaWdoLnRocmVzaG9sZHMgPSBjKDI1MDAwLCAyMDAwMDAwKSkKYGBgCgoKTm9ybWFsaXplIHRoZSBkYXRhLCB0aGVuIHJlZ3Jlc3Mgb3V0IGNvcnJlbGF0aW9uIHdpdGggdG90YWwgcmVhZHMKYGBge3J9CnRpc3MgPC0gTm9ybWFsaXplRGF0YShvYmplY3QgPSB0aXNzKQp0aXNzIDwtIFNjYWxlRGF0YShvYmplY3QgPSB0aXNzLCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJuUmVhZHMiLCAicGVyY2VudC5yaWJvIiwiUm40NXMiKSkKdGlzcyA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSB0aXNzLCBkby5wbG90ID0gVFJVRSwgeC5oaWdoLmN1dG9mZiA9IEluZiwgeS5jdXRvZmYgPSAwLjUpCmBgYAoKClJ1biBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzLgpgYGB7cn0KdGlzcyA8LSBSdW5QQ0Eob2JqZWN0ID0gdGlzcywgZG8ucHJpbnQgPSBGQUxTRSkKdGlzcyA8LSBQcm9qZWN0UENBKG9iamVjdCA9IHRpc3MsIGRvLnByaW50ID0gRkFMU0UpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTh9ClBDSGVhdG1hcChvYmplY3QgPSB0aXNzLCBwYy51c2UgPSAxOjMsIGNlbGxzLnVzZSA9IDUwMCwgZG8uYmFsYW5jZWQgPSBUUlVFLCBsYWJlbC5jb2x1bW5zID0gRkFMU0UsIG51bS5nZW5lcyA9IDgpCmBgYAoKTGF0ZXIgb24gKGluIEZpbmRDbHVzdGVycyBhbmQgVFNORSkgeW91IHdpbGwgcGljayBhIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuIFRoaXMgaGFzIHRoZSBlZmZlY3Qgb2Yga2VlcGluZyB0aGUgbWFqb3IgZGlyZWN0aW9ucyBvZiB2YXJpYXRpb24gaW4gdGhlIGRhdGEgYW5kLCBpZGVhbGx5LCBzdXByZXNzaW5nIG5vaXNlLiBUaGVyZSBpcyBubyBjb3JyZWN0IGFuc3dlciB0byB0aGUgbnVtYmVyIHRvIHVzZSwgYnV0IGEgZGVjZW50IHJ1bGUgb2YgdGh1bWIgaXMgdG8gZ28gdW50aWwgdGhlIHBsb3QgcGxhdGVhdXMuCgpgYGB7cn0KUENFbGJvd1Bsb3Qob2JqZWN0ID0gdGlzcykKYGBgCgpDaG9vc2UgdGhlIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuCmBgYHtyfQojIFNldCBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMuIApuLnBjcyA9IDEwCmBgYAoKClRoZSBjbHVzdGVyaW5nIGlzIHBlcmZvcm1lZCBiYXNlZCBvbiBhIG5lYXJlc3QgbmVpZ2hib3JzIGdyYXBoLiBDZWxscyB0aGF0IGhhdmUgc2ltaWxhciBleHByZXNzaW9uIHdpbGwgYmUgam9pbmVkIHRvZ2V0aGVyLiBUaGUgTG91dmFpbiBhbGdvcml0aG0gbG9va3MgZm9yIGdyb3VwcyBvZiBjZWxscyB3aXRoIGhpZ2ggbW9kdWxhcml0eS0tbW9yZSBjb25uZWN0aW9ucyB3aXRoaW4gdGhlIGdyb3VwIHRoYW4gYmV0d2VlbiBncm91cHMuIFRoZSByZXNvbHV0aW9uIHBhcmFtZXRlciBkZXRlcm1pbmVzIHRoZSBzY2FsZS4uLmhpZ2hlciByZXNvbHV0aW9uIHdpbGwgZ2l2ZSBtb3JlIGNsdXN0ZXJzLCBsb3dlciByZXNvbHV0aW9uIHdpbGwgZ2l2ZSBmZXdlci4KCkZvciB0aGUgdG9wLWxldmVsIGNsdXN0ZXJpbmcsIGFpbSB0byB1bmRlci1jbHVzdGVyIGluc3RlYWQgb2Ygb3Zlci1jbHVzdGVyLiBJdCB3aWxsIGJlIGVhc3kgdG8gc3Vic2V0IGdyb3VwcyBhbmQgZnVydGhlciBhbmFseXplIHRoZW0gYmVsb3cuCgpgYGB7cn0KIyBTZXQgcmVzb2x1dGlvbiAKcmVzLnVzZWQgPC0gMC41Cgp0aXNzIDwtIEZpbmRDbHVzdGVycyhvYmplY3QgPSB0aXNzLCByZWR1Y3Rpb24udHlwZSA9ICJwY2EiLCBkaW1zLnVzZSA9IDE6bi5wY3MsIAogICAgcmVzb2x1dGlvbiA9IHJlcy51c2VkLCBwcmludC5vdXRwdXQgPSAwLCBzYXZlLlNOTiA9IFRSVUUpCmBgYAoKVG8gdmlzdWFsaXplIApgYGB7cn0KIyBJZiBjZWxscyBhcmUgdG9vIHNwcmVhZCBvdXQsIHlvdSBjYW4gcmFpc2UgdGhlIHBlcnBsZXhpdHkuIElmIHlvdSBoYXZlIGZldyBjZWxscywgdHJ5IGEgbG93ZXIgcGVycGxleGl0eSAoYnV0IG5ldmVyIGxlc3MgdGhhbiAxMCkuCnRpc3MgPC0gUnVuVFNORShvYmplY3QgPSB0aXNzLCBkaW1zLnVzZSA9IDE6bi5wY3MsIHNlZWQudXNlID0gMTAsIHBlcnBsZXhpdHk9MzApCmBgYAoKYGBge3J9CiMgbm90ZSB0aGF0IHlvdSBjYW4gc2V0IGRvLmxhYmVsPVQgdG8gaGVscCBsYWJlbCBpbmRpdmlkdWFsIGNsdXN0ZXJzClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLmxhYmVsID0gVCkKYGBgCgpDaGVjayBleHByZXNzaW9uIG9mIGdlbmVzIG9mIGludGVyc2V0LgoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MjAsIGZpZy53aWR0aD04fQpnZW5lc190b19jaGVjayA9IGMoJ1ZpbScsJ0tydDUnLCdLcnQ4JywnUHRwcmMnLCdFcGNhbScsJ0gyLUFiMScsJ0gyLUFhJywnQ2QzNCcsJ0NkaDUnLCdDZDE0JywnVndmJywnU3lrJywnQ29sMWEyJywnVGltcDInLCdDZDc0JywnTGFwdG01JywnU2VscGxnJywnUGVjYW0xJywnRmFicDQnLCdTb3gxOCcsJ0ljYW0xJywnVGVrJywnVmNhbTEnLCdWZWdmYScsJ0FkaXBvcjEnLCdDYXIzJywnQWxhczInLCdBY3RhMicsJ0RjbicsJ015b2NkJywnVGFnbG4nLCdNeWgxMScsJ1MxMDBhNCcsJ0NkM2UnLCdQZGdmcmEnLCdLaXQnLCdHeXBhJywnQ29sNmEzJykKI2dlbmVzX3RvX2NoZWNrID0gYygnQWxiJywgJ0N5cDJmMicsICdDeXAyZTEnLCAnSGFtcCcpCgpGZWF0dXJlUGxvdCh0aXNzLCBnZW5lc190b19jaGVjaywgcHQuc2l6ZSA9IDEsIG5Db2wgPSAzKQpgYGAKCkRvdHBsb3RzIGxldCB5b3Ugc2VlIHRoZSBpbnRlbnNpdHkgb2YgZXhwcHJlc3Npb24gYW5kIHRoZSBmcmFjdGlvbiBvZiBjZWxscyBleHByZXNzaW5nIGZvciBlYWNoIG9mIHlvdXIgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MjV9CiMgVG8gY2hhbmdlIHRoZSB5LWF4aXMgdG8gc2hvdyByYXcgY291bnRzLCBhZGQgdXNlLnJhdyA9IFQuCkRvdFBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2ssIHBsb3QubGVnZW5kID0gVCkKYGBgCgpIb3cgYmlnIGFyZSB0aGUgY2x1c3RlcnM/CmBgYHtyfQp0YWJsZSh0aXNzQGlkZW50KQpgYGAKCldoaWNoIG1hcmtlcnMgaWRlbnRpZnkgYSBzcGVjaWZpYyBjbHVzdGVyPwoKYGBge3J9CmNsdXN0Lm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDAsIG9ubHkucG9zID0gVFJVRSwgbWluLnBjdCA9IDAuMjUsIHRocmVzaC51c2UgPSAwLjI1KQpgYGAKCmBgYHtyfQpwcmludCh4ID0gaGVhZCh4PSBjbHVzdC5tYXJrZXJzLCBuID0gMTApKQpgYGAKCllvdSBjYW4gYWxzbyBjb21wdXRlIGFsbCBtYXJrZXJzIGZvciBhbGwgY2x1c3RlcnMgYXQgb25jZS4gVGhpcyBtYXkgdGFrZSBzb21lIHRpbWUuCmBgYHtyfQp0aXNzLm1hcmtlcnMgPC0gRmluZEFsbE1hcmtlcnMob2JqZWN0ID0gdGlzcywgb25seS5wb3MgPSBUUlVFLCBtaW4ucGN0ID0gMC4yNSwgdGhyZXNoLnVzZSA9IDAuMjUpCmBgYAoKRGlzcGxheSB0aGUgdG9wIG1hcmtlcnMgeW91IGNvbXB1dGVkIGFib3ZlLgpgYGB7cn0KdGlzcy5tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24oNSwgYXZnX2RpZmYpCmBgYAoKIyMgQXNzaWduaW5nIGNlbGwgdHlwZSBpZGVudGl0eSB0byBjbHVzdGVycwoKQXQgYSBjb2Fyc2UgbGV2ZWwsIHdlIGNhbiB1c2UgY2Fub25pY2FsIG1hcmtlcnMgdG8gbWF0Y2ggdGhlIHVuYmlhc2VkIGNsdXN0ZXJpbmcgdG8ga25vd24gY2VsbCB0eXBlczoKCjA6IGhldGVyb2dlbm91cyBncm91cCBvZiBjZWxscwoxOiBlbmRvdGhlbGlhbCBjZWxscwoyOiBhZGlwb2N5dGVzCjM6IGVuZG90aGVsaWFsIGNlbGxzCjQ6IGZpYnJvYmxhc3RzCjU6IGhlbWF0b3BvZXRpYyAKCgoKCgpgYGB7cn0KIyBzdGFzaCBjdXJyZW50IGNsdXN0ZXIgSURzCnRpc3MgPC0gU3Rhc2hJZGVudChvYmplY3QgPSB0aXNzLCBzYXZlLm5hbWUgPSAiY2x1c3Rlci5pZHMiKQoKIyBlbnVtZXJhdGUgY3VycmVudCBjbHVzdGVyIElEcyBhbmQgdGhlIGxhYmVscyBmb3IgdGhlbQpjbHVzdGVyLmlkcyA8LSBjKDAsIDEsIDIsIDMsIDQsIDUpCmFubm90YXRpb24gPC0gYygiaGV0ZXJvZ2Vub3VzIGdyb3VwIG9mIGNlbGxzIiwgImVuZG90aGVsaWFsIGNlbGwiLCAiZXBpY2FyZGlhbCBhZGlwb2N5dGVzIiwgImVuZG90aGVsaWFsIGNlbGxzIiwgImZpYnJvYmxhc3RzIiwgImhlbWF0b3BvZXRpYyBjZWxscyIpCgp0aXNzQG1ldGEuZGF0YVssJ2Fubm90YXRpb24nXSA8LSBwbHlyOjptYXB2YWx1ZXMoeCA9IHRpc3NAbWV0YS5kYXRhJGNsdXN0ZXIuaWRzLCBmcm9tID0gY2x1c3Rlci5pZHMsIHRvID0gYW5ub3RhdGlvbikKClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLmxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDAuNSwgZ3JvdXAuYnk9J2Fubm90YXRpb24nKQpgYGAKCgojIyBDaGVja2luZyBmb3IgYmF0Y2ggZWZmZWN0cwoKYGBge3J9CmhlYWQodGlzc0BtZXRhLmRhdGEpCmBgYAoKCgpDb2xvciBieSBtZXRhZGF0YSwgbGlrZSBwbGF0ZSBiYXJjb2RlLCB0byBjaGVjayBmb3IgYmF0Y2ggZWZmZWN0cy4KYGBge3J9ClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLnJldHVybiA9IFRSVUUsIGdyb3VwLmJ5ID0gInBsYXRlLmJhcmNvZGUiKQpgYGAKClByaW50IGEgdGFibGUgc2hvd2luZyB0aGUgY291bnQgb2YgY2VsbHMgaW4gZWFjaCBpZGVudGl0eSBjYXRlZ29yeSBmcm9tIGVhY2ggcGxhdGUuCgpgYGB7cn0KdGFibGUoYXMuY2hhcmFjdGVyKHRpc3NAaWRlbnQpLCBhcy5jaGFyYWN0ZXIodGlzc0BtZXRhLmRhdGEkcGxhdGUuYmFyY29kZSkpCmBgYAoKCiMgU3Vic2V0IGFuZCBpdGVyYXRlCgpXZSBjYW4gcmVwZWF0IHRoZSBhYm92ZSBhbmFseXNpcyBvbiBhIHN1YnNldCBvZiBjZWxscywgZGVmaW5lZCB1c2luZyBjbHVzdGVyIElEcyBvciBzb21lIG90aGVyIG1ldGFkYXRhLiBUaGlzIGlzIGEgZ29vZCB3YXkgdG8gZHJpbGwgZG93biBhbmQgZmluZCBzdWJzdHJ1Y3R1cmUuCgojIyBGaXJzdCBzdWJzZXQKCmBgYHtyfQojIFN1YnNldCBkYXRhIGJhc2VkIG9uIGNsdXN0ZXIgaWQKc3VidGlzcyA8LSBTdWJzZXREYXRhKG9iamVjdCA9IHRpc3MsIGlkZW50LnVzZSA9IGMoMCksIGRvLmNlbnRlciA9IEYsIGRvLnNjYWxlID0gRiwgY2VsbHMudXNlID0gKQoKIyBUbyBzdWJzZXQgZGF0YSBiYXNlZCBvbiBhbm5vdGF0aW9uIG9yIG90aGVyIG1ldGFkYXRhLCB5b3UgY2FuIGV4cGxpY2l0bHkgcGFzcyBjZWxsIG5hbWVzCgojIGFubm8gPSAndGh5bW9jeXRlJwojIGNlbGxzLnRvLnVzZSA9IHRpc3NAY2VsbC5uYW1lc1t3aGljaCh0aXNzQG1ldGEuZGF0YSRhbm5vdGF0aW9uID09IGFubm8pXQojIHN1YnRpc3MgPC0gU3Vic2V0RGF0YShvYmplY3QgPSB0aXNzLCBjZWxscy51c2UgPSBjZWxscy50by51c2UsIGRvLmNlbnRlciA9IEYsIGRvLnNjYWxlID0gRikKCmBgYAoKYGBge3J9CnN1YnRpc3MgPC0gTm9ybWFsaXplRGF0YShvYmplY3QgPSBzdWJ0aXNzKQpzdWJ0aXNzIDwtIFNjYWxlRGF0YShvYmplY3QgPSBzdWJ0aXNzLCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJuUmVhZHMiLCAicGVyY2VudC5yaWJvIiwiUm40NXMiKSkKYGBgCgpgYGB7cn0Kc3VidGlzcyA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSBzdWJ0aXNzLCBkby5wbG90ID0gVFJVRSwgeC5oaWdoLmN1dG9mZiA9IEluZiwgeS5jdXRvZmYgPSAwLjgpCnN1YnRpc3MgPC0gUnVuUENBKG9iamVjdCA9IHN1YnRpc3MsIHBjcy5jb21wdXRlID0gMjApCnN1YnRpc3MgPC0gUHJvamVjdFBDQShvYmplY3QgPSBzdWJ0aXNzLCBkby5wcmludCA9IEZBTFNFKQpgYGAKCgpSdW4gUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcy4KYGBge3J9CnN1YnRpc3MgPC0gUnVuUENBKG9iamVjdCA9IHN1YnRpc3MsIGRvLnByaW50ID0gRkFMU0UpCnN1YnRpc3MgPC0gUHJvamVjdFBDQShvYmplY3QgPSBzdWJ0aXNzLCBkby5wcmludCA9IEZBTFNFKQpgYGAKCmBgYHtyfQojIElmIHRoaXMgZmFpbHMgZm9yIHlvdXIgc3Vic2V0LCBpdCBtYXkgYmUgdGhhdCBjZWxscy51c2UgaXMgbW9yZSBjZWxscyB0aGFuIHlvdSBoYXZlIGxlZnQhIFRyeSByZWR1Y2luZyBpdC4KUENIZWF0bWFwKG9iamVjdCA9IHN1YnRpc3MsIHBjLnVzZSA9IDE6MywgY2VsbHMudXNlID0gMjAwLCBkby5iYWxhbmNlZCA9IFRSVUUsIGxhYmVsLmNvbHVtbnMgPSBGQUxTRSwgbnVtLmdlbmVzID0gMTIpCmBgYAoKTGF0ZXIgb24gKGluIEZpbmRDbHVzdGVycyBhbmQgVFNORSkgeW91IHdpbGwgcGljayBhIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuIFRoaXMgaGFzIHRoZSBlZmZlY3Qgb2Yga2VlcGluZyB0aGUgbWFqb3IgZGlyZWN0aW9ucyBvZiB2YXJpYXRpb24gaW4gdGhlIGRhdGEgYW5kLCBpZGVhbGx5LCBzdXByZXNzaW5nIG5vaXNlLiBUaGVyZSBpcyBubyBjb3JyZWN0IGFuc3dlciB0byB0aGUgbnVtYmVyIHRvIHVzZSwgYnV0IGEgZGVjZW50IHJ1bGUgb2YgdGh1bWIgaXMgdG8gZ28gdW50aWwgdGhlIHBsb3QgcGxhdGVhdXMuCgpgYGB7cn0KUENFbGJvd1Bsb3Qob2JqZWN0ID0gc3VidGlzcykKYGBgCgpDaG9vc2UgdGhlIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuCmBgYHtyfQojIFNldCBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMuIApzdWIubi5wY3MgPSAxMApgYGAKCgpUaGUgY2x1c3RlcmluZyBpcyBwZXJmb3JtZWQgYmFzZWQgb24gYSBuZWFyZXN0IG5laWdoYm9ycyBncmFwaC4gQ2VsbHMgdGhhdCBoYXZlIHNpbWlsYXIgZXhwcmVzc2lvbiB3aWxsIGJlIGpvaW5lZCB0b2dldGhlci4gVGhlIExvdXZhaW4gYWxnb3JpdGhtIGxvb2tzIGZvciBncm91cHMgb2YgY2VsbHMgd2l0aCBoaWdoIG1vZHVsYXJpdHktLW1vcmUgY29ubmVjdGlvbnMgd2l0aGluIHRoZSBncm91cCB0aGFuIGJldHdlZW4gZ3JvdXBzLiBUaGUgcmVzb2x1dGlvbiBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB0aGUgc2NhbGUuLi5oaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgbW9yZSBjbHVzdGVycywgbG93ZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgZmV3ZXIuCgpgYGB7cn0KIyBTZXQgcmVzb2x1dGlvbiAKc3ViLnJlcy51c2VkIDwtIDEuNQoKc3VidGlzcyA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gc3VidGlzcywgcmVkdWN0aW9uLnR5cGUgPSAicGNhIiwgZGltcy51c2UgPSAxOnN1Yi5uLnBjcywgCiAgICByZXNvbHV0aW9uID0gc3ViLnJlcy51c2VkLCBwcmludC5vdXRwdXQgPSAwLCBzYXZlLlNOTiA9IFRSVUUsIGZvcmNlLnJlY2FsYyA9IFRSVUUpCmBgYAoKVG8gdmlzdWFsaXplIApgYGB7cn0KIyBJZiBjZWxscyBhcmUgdG9vIHNwcmVhZCBvdXQsIHlvdSBjYW4gcmFpc2UgdGhlIHBlcnBsZXhpdHkuIElmIHlvdSBoYXZlIGZldyBjZWxscywgdHJ5IGEgbG93ZXIgcGVycGxleGl0eSAoYnV0IG5ldmVyIGxlc3MgdGhhbiAxMCkuCnN1YnRpc3MgPC0gUnVuVFNORShvYmplY3QgPSBzdWJ0aXNzLCBkaW1zLnVzZSA9IDE6c3ViLm4ucGNzLCBzZWVkLnVzZSA9IDEwLCBwZXJwbGV4aXR5PTEwKQpgYGAKCmBgYHtyfQojIG5vdGUgdGhhdCB5b3UgY2FuIHNldCBkby5sYWJlbD1UIHRvIGhlbHAgbGFiZWwgaW5kaXZpZHVhbCBjbHVzdGVycwpUU05FUGxvdChvYmplY3QgPSBzdWJ0aXNzLCBkby5sYWJlbCA9IFQpCmBgYAoKYGBge3J9CnN1YnRpc3MubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhvYmplY3QgPSBzdWJ0aXNzLCBvbmx5LnBvcyA9IFRSVUUsIG1pbi5wY3QgPSAwLjI1LCB0aHJlc2gudXNlID0gMC4yNSkKYGBgCgpgYGB7cn0Kc3VidGlzcy5tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24oNiwgYXZnX2RpZmYpCmBgYAoKQ2hlY2sgZXhwcmVzc2lvbiBvZiBnZW5lcyBvZiBpbnRlcnNldC4KYGBge3IsIGZpZy5oZWlnaHQ9MTYsIGZpZy53aWR0aD04fQpnZW5lc190b19jaGVjayA9IChzdWJ0aXNzLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3Bfbig2LCBhdmdfZGlmZikpJGdlbmUKIyBnZW5lc190b19jaGVjayA9IGMoJ1ZpbScsJ0tydDUnLCdLcnQ4JywnUHRwcmMnLCdFcGNhbScsJ0gyLUQxJywnSDItQWEnLCdIMi1BYjEnLCdDZDM0JywnSXRnYW0nLCdTeWsnLCdDb2wxYTInLCdUaW1wMicsJ0NkNzQnLCdMYXB0bTUnLCdTZWxwbGcnLCdGYWJwNCcsJ0ljYW0xJywnVmNhbTEnLCdBZGlwb3IxJywnQWxhczInLCdDbm4xJywnQWN0YTInLCdEY24nLCdNeW9jZCcsJ01tcDInLCdMbW5hJywnRWxuJywnQ29sM2ExJywnQ29sNGExJywnQ29sMWExJywnUGRnZnJhJywnR3lwYScsJ0NvbDZhMycsJ1BlY2FtMScsJ1BkZ2ZyYicsJ1BzbWI4JywnTXloMTAnLCdUcG00JywnQ2FsZDEnLCdSYnAxJywgJ0NkMzYnKQoKRmVhdHVyZVBsb3Qoc3VidGlzcywgZ2VuZXNfdG9fY2hlY2ssIHB0LnNpemUgPSAxKQpgYGAKCkRvdHBsb3RzIGxldCB5b3Ugc2VlIHRoZSBpbnRlbnNpdHkgb2YgZXhwcHJlc3Npb24gYW5kIHRoZSBmcmFjdGlvbiBvZiBjZWxscyBleHByZXNzaW5nIGZvciBlYWNoIG9mIHlvdXIgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MjV9CiMgVG8gY2hhbmdlIHRoZSB5LWF4aXMgdG8gc2hvdyByYXcgY291bnRzLCBhZGQgdXNlLnJhdyA9IFQuCkRvdFBsb3Qoc3VidGlzcywgZ2VuZXNfdG9fY2hlY2ssIHBsb3QubGVnZW5kID0gVCkKYGBgCgpIb3cgYmlnIGFyZSB0aGUgY2x1c3RlcnM/CmBgYHtyfQp0YWJsZShzdWJ0aXNzQGlkZW50KQpgYGAKCiMjIENoZWNraW5nIGZvciBiYXRjaCBlZmZlY3RzCgpDb2xvciBieSBtZXRhZGF0YSwgbGlrZSBwbGF0ZSBiYXJjb2RlLCB0byBjaGVjayBmb3IgYmF0Y2ggZWZmZWN0cy4KYGBge3J9ClRTTkVQbG90KG9iamVjdCA9IHN1YnRpc3MsIGRvLnJldHVybiA9IFRSVUUsIGdyb3VwLmJ5ID0gInBsYXRlLmJhcmNvZGUiKQpgYGAKClByaW50IGEgdGFibGUgc2hvd2luZyB0aGUgY291bnQgb2YgY2VsbHMgaW4gZWFjaCBpZGVudGl0eSBjYXRlZ29yeSBmcm9tIGVhY2ggcGxhdGUuCgpgYGB7cn0KdGFibGUoYXMuY2hhcmFjdGVyKHN1YnRpc3NAaWRlbnQpLCBhcy5jaGFyYWN0ZXIoc3VidGlzc0BtZXRhLmRhdGEkcGxhdGUuYmFyY29kZSkpCmBgYAoKCgojIyMgQXNzaWduaW5nIHN1YmFubm90YXRpb25zCgpGb3IgdGhlIHN1YnNldHMsIHdlIHByb2R1Y2Ugc3ViYW5ub3RhdGlvbnMuIFRoZXNlIHdpbGwgYmUgd3JpdHRlbiBiYWNrIGFzIG1ldGFkYXRhIGluIHRoZSBvcmlnaW5hbCBvYmplY3QsIHNvIHdlIGNhbiBzZWUgYWxsIHN1YmFubm90YXRpb25zIHRvZ2V0aGVyLgoKSWYgc29tZSBvZiB0aGUgY2x1c3RlcnMgeW91IGZpbmQgaW4gdGhlIHN1YnNldCBkZXNlcnZlIGFkZGl0aW9uYWwgYW5ub3RhdGlvbiwgeW91IGNhbiBhZGQgdGhhdCByaWdodCBoZXJlLiBVc2UgTkEgZm9yIGNsdXN0ZXJzIGZvciB3aGljaCBubyBzdWJhbm5vdGF0aW9uIGlzIG5lZWRlZC4KCmBgYHtyfQpzdWJjbHVzdGVyLmlkcyA8LSBjKDAsIDEsMikKc3ViYW5ub3RhdGlvbiA8LSBjKE5BLCAiZXBpY2FyZGlhbCBhZGlwb2N5dGUiLCAic21vb3RoIG11c2NsZSBjZWxsIikKCnN1YnRpc3NAbWV0YS5kYXRhWywnc3ViYW5ub3RhdGlvbiddIDwtIHBseXI6Om1hcHZhbHVlcyh4ID0gc3VidGlzc0BpZGVudCwgZnJvbSA9IHN1YmNsdXN0ZXIuaWRzLCB0byA9IHN1YmFubm90YXRpb24pCgp0aXNzQG1ldGEuZGF0YVtzdWJ0aXNzQGNlbGwubmFtZXMsJ3N1YmFubm90YXRpb24nXSA8LSBhcy5jaGFyYWN0ZXIoc3VidGlzc0BtZXRhLmRhdGEkc3ViYW5ub3RhdGlvbikKClRTTkVQbG90KG9iamVjdCA9IHN1YnRpc3MsIGRvLmxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDAuNSwgZ3JvdXAuYnk9J3N1YmFubm90YXRpb24nKQpgYGAKClNhdmUgdGhlIHRpc3N1ZSBvYmplY3Qgd2l0aCB1cGRhdGVkIGFubm90YXRpb25zCmBgYHtyfQpmaWxlbmFtZSA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJ3Rpc3N1ZV9zZXVyYXRfcm9iaicsIAogICAgICAgICAgICAgICAgICAgICBwYXN0ZTAodGlzc3VlX29mX2ludGVyZXN0LCAiX3NldXJhdF90aXNzLlJvYmoiKSkKcHJpbnQoZmlsZW5hbWUpCnNhdmUodGlzcywgZmlsZT1maWxlbmFtZSkKYGBgCgojIEV4cG9ydCB0aGUgZmluYWwgbWV0YWRhdGEKClNvIHRoYXQgQmlvaHViIGNhbiBlYXNpbHkgY29tYmluZSBhbGwgeW91ciBhbm5vdGF0aW9ucywgcGxlYXNlIGV4cG9ydCB0aGVtIGFzIGEgc2ltcGxlIGNzdi4KCmBgYHtyfQp3cml0ZS5jc3YodGlzc0BtZXRhLmRhdGFbLGMoJ3BsYXRlLmJhcmNvZGUnLCdhbm5vdGF0aW9uJywnc3ViYW5ub3RhdGlvbicpXSxmaWxlID1wYXN0ZTAoc2F2ZV9kaXIsIi8iLCB0aXNzdWVfb2ZfaW50ZXJlc3QsIl9hbm5vdGF0aW9uLmNzdiIpKQpgYGAKCgoK